#include <cstdio>
#include <vector>
#include <string>
#include <cassert>
#include <map>
#include <iostream>

using namespace std;

const char* SOURCE_FILE = "arxiv.lj.mc";
const char* DEST_FILE = "arxiv.gml";

const int MAX_LEN = 1024;

map<string, int> indexes;
map<int, string> names;

map<int, vector<int> > outEdges;
map<int, vector<int> > inEdges;

int getIndex(string name)
{
	if ( indexes.find(name)==indexes.end() )
	{
		int tot = (int)indexes.size();
		names[tot] = name;
		indexes[name] = tot;
	}

	return indexes[name];
}

void Read()
{
	FILE* f = fopen(SOURCE_FILE, "r");
	char* buf = new char[MAX_LEN];
	while ( fgets(buf, MAX_LEN, f)!=NULL )
	{
		char name1[MAX_LEN];
		int cnt1, cnt2;
		if ( sscanf(buf, "%s %d %d", name1, &cnt1, &cnt2) != 3 ) continue;
		if ( strlen(name1)==0 ) continue;

		int ind1 = getIndex(string(name1));

		for (int i=0;i<cnt1;i++)
		{
			fgets(buf, MAX_LEN, f);
			char name2[MAX_LEN];
			sscanf(buf, " > %s", name2);
			int ind2 = getIndex(string(name2));
			if ( ind1==ind2 ) continue;

			outEdges[ind1].push_back(ind2);
			inEdges[ind2].push_back(ind1);
		}

		for (int i=0;i<cnt2;i++)
		{
			fgets(buf, MAX_LEN, f);
			char name2[MAX_LEN];
			sscanf(buf, " < %s", name2);
			int ind2 = getIndex(string(name2));
			if ( ind1==ind2 ) continue;

			outEdges[ind2].push_back(ind1);
			inEdges[ind1].push_back(ind2);
		}
	}

	delete[] buf;
	fclose(f);
	
	cerr<<"Total vertexes: "<<indexes.size()<<"\n";
}

void Write()
{
	FILE* f = fopen(DEST_FILE, "w");
	
	fprintf(f, "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n");
	fprintf(f, "<grpahml >\n");
	fprintf(f, "<graph directed='false' id='insert here!'>\n");

	for (map<int, vector<int> >::iterator iter = outEdges.begin(); iter != outEdges.end(); iter++)
	{
		int id = (*iter).first;
		string name = names[id];
		fprintf(f, "	<node id='%s' />\n", name.c_str());
		
		assert(inEdges[id].size() == outEdges[id].size());
	}
	fprintf(f, "\n");

	for (map<int, vector<int> >::iterator iter = outEdges.begin(); iter != outEdges.end(); iter++)
	{
		int id = (*iter).first;
		vector<int> neig = (*iter).second;
		string name = names[id];
		
		for (int j = 0; j < (int)neig.size(); j++)
			fprintf(f, "	<edge source='%s' target='%s'/>\n", name.c_str(), names[neig[j]].c_str());
	}
	
	fprintf(f, "</graph>\n");
	fprintf(f, "</grpahml>\n");
	
	fclose(f);
}

int main()
{
	Read();
	Write();
	return 0;
}
